/**
 * 
 */
package ro.dandanciu.webgallery.ui.users;

import java.util.List;

import org.apache.log4j.Logger;

import ro.dandanciu.webgallery.domainmodel.User;
import ro.dandanciu.webgallery.services.UserServices;
import ro.dandanciu.webgallery.ui.general.WebGalleryAction;

import com.opensymphony.xwork2.Preparable;

/**
 * @author Dan
 *
 */
public class EditUserAction extends WebGalleryAction implements Preparable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(EditUserAction.class);
	
	private static final String REGEXP_EMAIL = "^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$";
	
	private UserServices userService;
	
	/**
	 * Modes of submitting this action
	 * <ul>
	 * 	<li>R - register</li>
	 * 	<li>A - add</li>
	 * 	<li>E - edit</li>
	 * 	<li>S - save</li>
	 * 	<li>L - list users</li>
	 * </ul>
	 */
	private String mode = "L";
	
	/* modes */
	private static final String REGISTER_MODE = "R";
	
	private static final String ADD_MODE = "A";
	
	private static final String LIST_MODE = "L";
	
	private static final String EDIT_MODE = "E";

	private static final String SAVE_MODE = "S";

	private static final String DELETE_MODE = "D";

	/* mappings */
	private static final String MAPPING_REGISTER = "register";

	private static final String MAPPING_EDIT = "edit";

	/* form fields */
	private String userId;
	
	private String username;
	
	private String password;
	
	private String passwordConfirmation;
	
	private String email;
	
	private boolean admin;
	
	private List<User> users;
	
	private boolean ignorePassword = false;
	
	private String[] selectedUsers;
	
	private String query = "";
	
	public UserServices getUserService() {
		return userService;
	}

	public void setUserService(UserServices userService) {
		this.userService = userService;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPasswordConfirmation() {
		return passwordConfirmation;
	}

	public void setPasswordConfirmation(String passwordCheck) {
		this.passwordConfirmation = passwordCheck;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public boolean isAdmin() {
		return admin;
	}

	public void setAdmin(boolean isAdmin) {
		this.admin = isAdmin;
	}

	public EditUserAction(UserServices userService) {
		this.userService = userService;
	}

	public String execute() throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("execute() - start");
		}
		String forward = null;
	 	
		if(REGISTER_MODE.equals(mode)) {
			forward = MAPPING_REGISTER; 
	 	} else if (ADD_MODE.equals(mode)) {
			forward = executeAdd();
	 	} else if (LIST_MODE.equals(mode)) {
			forward = executeList();
	 	} else if (EDIT_MODE.equals(mode)) {
			forward = executeEdit();
	 	} else if (SAVE_MODE.equals(mode)) {
			forward = executeSave();
	 	} else if (DELETE_MODE.equals(mode)) {
			forward = executeDelete();
	 	} else {
	 		forward = setMessage("failure");
	 	}
	 

		if (logger.isDebugEnabled()) {
			logger.debug("forward: " + forward);
			logger.debug("execute() - end");
		}
		return forward;
	 }

	private String executeDelete() {
		if (selectedUsers != null) {
			for(String userId : selectedUsers) {
				userService.delete(userId, false);
			}
			return setMessage("user.delete.success");
		} 
		return setMessage("user.no.users.selected");
	}

	private String executeSave() {
		if(!validateRegistration()){
			return MAPPING_EDIT;
		}
		User user = extractUser();
		
		userService.save(userId, user, ignorePassword, getSessionUser().getUserId());
		return setMessage("user.save.success");
	}

	private String executeEdit() {
		User user = userService.getUserByUserId(userId);
		userId = user.getUserId();
		username = user.getUserName();
		//passwords are not being set, 
		//so when editing it is empty do not update it
		password = "";
		passwordConfirmation = "";
		email = user.getEmail();
		admin = user.isAdmin();
		return MAPPING_EDIT;
	}

	private String executeList() {
		users = userService.getUsers(query);
		return "list";
	}

	private String executeAdd() {
		if(!isSessionValid()) {
			return LOGIN;
		}
		if(!validateRegistration()){
			return MAPPING_REGISTER;
		}
		User user = extractUser();
		
		userService.save(user, getSessionUser().getUserId());
		return setMessage("user.add.success");
	}

	private User extractUser() {
		User user = new User();		
		user.setUserId(userId);
		user.setUserName(username);
		user.setPassword(password);
		user.setEmail(email);
		user.setAdmin(admin);
		return user;
	}

	private boolean validateRegistration() {
		boolean flag = true;
		if(!ignorePassword && (password == null || passwordConfirmation ==null ||
				"".equals(password) || "".equals(passwordConfirmation) ||
				!password.equals(passwordConfirmation))) {
			addFieldError("password", "register.password.invalid");
			flag = false;
		}
		if(email != null && !email.matches(REGEXP_EMAIL)) {
			addFieldError("email", "register.email.invalid");
			flag = false;
		}
		return flag;
	}

	public String getMode() {
		return mode;
	}

	public void setMode(String mode) {
		this.mode = mode;
	}

	
	public void prepare() throws Exception {
		//TODO[prepare] add code
	}

	public List<User> getUsers() {
		return users;
	}

	public void setUsers(List<User> users) {
		this.users = users;
	}

	public boolean isIgnorePassword() {
		return ignorePassword;
	}

	public void setIgnorePassword(boolean changePassword) {
		this.ignorePassword = changePassword;
	}

	public String[] getSelectedUsers() {
		return selectedUsers;
	}

	public void setSelectedUsers(String[] selectedUsers) {
		this.selectedUsers = selectedUsers;
	}

	public String getQuery() {
		return query;
	}

	public void setQuery(String query) {
		this.query = query;
	}

}
